﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Drawing;
using System.Data;
using System.Drawing.Design;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using Kugar.Core.BaseStruct;
using Kugar.Core.Collections;
using Kugar.Core.ExtMethod;


namespace Kugar.UI.WinForm
{

    /// <summary>
    ///     合计行的基类
    /// </summary>
    [DesignerSerializer(typeof(TotalColumnRowBaseCodeDom), typeof(CodeDomSerializer))]
    [Designer(typeof(TotalColumnRowBaseControlDesigner))]
    public abstract partial class TotalColumnRowBase : UserControl
    {
        private DataGridView _gridSource = null;
        protected Dictionary<DataGridViewColumn, Label> labelMappingCache = new Dictionary<DataGridViewColumn, Label>();
        protected Dictionary<DataGridViewColumn, Label> calcColumnMappingCache = new Dictionary<DataGridViewColumn, Label>();
        private string _headerText = "合计";
        private Color _totalCellBackColor = Color.Transparent;
        private Color _totalCellForeColor = Color.Black;
        private BorderStyle _totalCellBorderStyle = BorderStyle.FixedSingle;

        private Color _headerCellBackColor =Color.Transparent;
        private Color _headerCellForeColor = Color.Black;


        public TotalColumnRowBase()
        {
            Columns = new DictionaryEx<DataGridViewColumn, TotalColumnConfig>();

            Columns.DictionaryChanged += Columns_DictionaryChanged;

            InitializeComponent();

            panelLabelCollection.Padding = new Padding(0);
            panelLabelCollection.Top = 0;
            panelLabelCollection.Height = this.ClientSize.Height;

            HeaderTextLabel.AutoSize = false;
            HeaderTextLabel.Height = this.ClientSize.Height;
            HeaderTextLabel.Left = 0;
            HeaderTextLabel.Top = 0;
            HeaderTextLabel.TextAlign = ContentAlignment.MiddleCenter;
            HeaderTextLabel.Margin = new Padding(0);
            HeaderTextLabel.Text = _headerText;

            TotalCellBorderStyle = BorderStyle.FixedSingle;


        }

        void Columns_DictionaryChanged(object sender, DictionaryChangedEventArgs<DataGridViewColumn> e)
        {
            this.Refresh();
        }

        [DefaultValue(null)]
        public DataGridView GridSource
        {
            set
            {
                if (_gridSource != value)
                {
                    if (_gridSource != null)
                    {
                        UnHandleEvents(_gridSource);
                    }

                    if (value != null)
                    {
                        HandleEvents(value);
                    }

                    _gridSource = value;
                }

                this.Refresh();
            }
            get { return _gridSource; }
        }

        //行标题配置

        /// <summary>
        ///     行的标题文本
        /// </summary>
        [DefaultValue("合计")]
        public string HeaderText
        {
            set
            {
                if (_headerText != value)
                {
                    _headerText = value;
                    HeaderTextLabel.Text = value;
                }
            }
            get { return _headerText; }
        }

        /// <summary>
        ///     行标题的背景色
        /// </summary>
        [DefaultValue(typeof(Color), "Transparent")]
        [TypeConverter(typeof(ColorConverter))]
        public Color HeaderBackColor
        {
            set
            {
                if (_headerCellBackColor != value)
                {
                    _headerCellBackColor = value;

                    RefreshLabelControl();
                }
            }
            get { return _headerCellBackColor; }
        }

        /// <summary>
        ///     行标题的前景色
        /// </summary>
        [DefaultValue(typeof(Color), "Black")]
        [TypeConverter(typeof(ColorConverter))]
        public Color HeaderForeCore
        {
            set
            {
                if (value != _headerCellForeColor)
                {
                    _headerCellForeColor = value;
                    RefreshLabelControl();
                }
            }
            get
            {
                return _headerCellForeColor;
            }
        }


        /// <summary>
        ///     合计列集合
        /// </summary>
        [Localizable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [Editor(typeof(TotalColumnRowConfigUITypeDesign), typeof(UITypeEditor))]
        public DictionaryEx<DataGridViewColumn, TotalColumnConfig> Columns { get; private set; }

        //合计单元格的配置
        /// <summary>
        ///     统计单元格背景色
        /// </summary>
        [DefaultValue(typeof(Color), "Transparent")]
        [TypeConverter(typeof(ColorConverter))]
        public Color TotalCellBackColor
        {
            set
            {
                if (_totalCellBackColor != value)
                {
                    _totalCellBackColor = value;

                    RefreshLabelControl();

                    //HeaderTextLabel.BackColor = value;
                }
            }
            get { return _totalCellBackColor; }
        }

        /// <summary>
        ///     统计单元格前景色
        /// </summary>
        [DefaultValue(typeof(Color), "Black")]
        [TypeConverter(typeof(ColorConverter))]
        public Color TotalCellForeColor
        {
            set
            {
                if (_totalCellForeColor != value)
                {
                    _totalCellForeColor = value;

                    RefreshLabelControl();

                }
            }
            get { return _totalCellForeColor; }
        }

        /// <summary>
        ///     统计单元格的边框类型
        /// </summary>
        [DefaultValue(BorderStyle.FixedSingle)]
        public BorderStyle TotalCellBorderStyle
        {
            set
            {
                if (_totalCellBorderStyle != value)
                {
                    _totalCellBorderStyle = value;

                    RefreshLabelControl();
                }
            }
            get { return _totalCellBorderStyle; }
        }

        protected override void OnResize(EventArgs e)
        {
            LayoutBaseControl();



            base.OnResize(e);
        }

        public override void Refresh()
        {
            CleanAllLabel();
            LayoutBaseControl();
            ReLoadLabelControl();
            RefreshAllLabelValue();

            base.Refresh();


        }

        #region "处理Grid的事件"

        void GridSource_Scroll(object sender, ScrollEventArgs e)
        {
            if (e.ScrollOrientation == ScrollOrientation.VerticalScroll)
            {
                return;
            }

            panelLabelCollection.HorizontalScroll.Value = e.NewValue;

        }

        void GridSource_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
        {
            if (!labelMappingCache.ContainsKey(e.Column))
            {
                return;
            }

            var lbl = labelMappingCache[e.Column];

            lbl.Width = e.Column.Width;

            LayoutScollValue();
        }

        void GridSource_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
        {
            RefreshAllLabelValue();
        }

        void GridSource_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            RefreshLabelValue(GridSource.Columns[e.ColumnIndex]);
        }

        void Columns_CollectionChanged(object sender, CollectionChangeEventArgs e)
        {
            CleanAllLabel();
            LayoutBaseControl();
            ReLoadLabelControl();
            RefreshAllLabelValue();
        }

        void GridSource_Resize(object sender, EventArgs e)
        {
            base.Size = _gridSource.Size;

            this.OnResize(null);
        }

        #endregion


        protected abstract object GetColumnTotalValue(DataGridViewColumn column);

        //刷新所有列的合计值
        private void RefreshAllLabelValue()
        {
            if (_gridSource == null || _gridSource.Columns.Count <= 0 || labelMappingCache.Count <= 0)
            {
                CleanAllLabel();
                return;
            }

            foreach (var label in calcColumnMappingCache)
            {
                RefreshLabelValue(label.Key);
            }
        }

        //刷新指定列的合计值
        private void RefreshLabelValue(DataGridViewColumn column)
        {
            if (_gridSource == null || !_gridSource.Columns.Contains(column) || !calcColumnMappingCache.ContainsKey(column))
            {
                return;
            }

            var value = GetColumnTotalValue(column);

            var config = Columns[column];

            var label = calcColumnMappingCache[column];

            var displayValue = "";

            if (value == null)
            {
                displayValue = value.ToStringEx();
            }
            else
            {
                if (!config.FormatString.IsNullOrEmpty())
                {
                    displayValue = value.GetValueFormatString(config.FormatString);
                }
            }

            label.Text = displayValue;

        }

        //当修改了Label控件的外观参数的时候，使用该函数刷新所有合计行的属性
        private void RefreshLabelControl()
        {
            foreach (var label in labelMappingCache)
            {
                var lbl = label.Value;

                lbl.Width = label.Key.Width;// +column.DividerWidth;
                lbl.Height = panelLabelCollection.ClientSize.Height;
                lbl.BackColor = this.TotalCellBackColor;
                lbl.ForeColor = this.TotalCellForeColor;
                lbl.TextAlign = ContentAlignment.MiddleCenter;
                lbl.BorderStyle = this.TotalCellBorderStyle;
            }
        }

        //重新刷新所有的Label
        private void ReLoadLabelControl()
        {
            if (_gridSource == null || _gridSource.Columns.Count <= 0)
            {
                CleanAllLabel();
                return;
            }

            DataGridViewColumn column = null;
            var columnCount = _gridSource.Columns.GetColumnCount(DataGridViewElementStates.Visible);

            if (columnCount <= 0)
            {
                CleanAllLabel();
                return;
            }

            for (int i = 0; i < columnCount; i++)
            {
                if (column == null)
                {
                    column = _gridSource.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
                }
                else
                {
                    column = _gridSource.Columns.GetNextColumn(column, DataGridViewElementStates.Visible,
                                                               DataGridViewElementStates.None);
                }

                if (column == null)
                {
                    break;
                }

                var lbl = BuildSumLabel(column);

                panelLabelCollection.Controls.Add(lbl);

                labelMappingCache.Add(column, lbl);

                if (Columns.ContainsKey(column))
                {
                    calcColumnMappingCache.Add(column, lbl);
                }

            }

        }

        //清除所有label
        private void CleanAllLabel()
        {
            panelLabelCollection.Controls.Clear();

            foreach (var label in labelMappingCache)
            {
                label.Value.Dispose();
            }

            labelMappingCache.Clear();
            calcColumnMappingCache.Clear();
        }

        //重新布局HeaderTextLabel和flowpanel的大小以及位置
        private void LayoutBaseControl()
        {
            if (GridSource != null)
            {
                this.Width = _gridSource == null ? 0 : _gridSource.Width;

                HeaderTextLabel.Visible = GridSource.RowHeadersVisible;

                if (GridSource.RowHeadersVisible)
                {
                    HeaderTextLabel.Width = GridSource.RowHeadersWidth;
                }

                panelLabelCollection.Left = CalcPanelLeft();
                panelLabelCollection.Width = CalcPanelWidth();


            }

            panelLabelCollection.Height = this.ClientSize.Height;
            HeaderTextLabel.Top = 0;
            HeaderTextLabel.Height = this.ClientSize.Height;

            RefreshLabelControl();
        }

        //计算FlowPanel的宽度
        private int CalcPanelWidth()
        {
            if (GridSource != null)
            {
                var resual = 0;

                if (GridSource.RowHeadersVisible)
                {
                    resual = this.ClientSize.Width - CalcPanelLeft();// HeaderTextLabel.Width;
                }
                else
                {
                    resual = this.ClientSize.Width;
                }

                if (IsGridHasHScollBar())
                {
                    resual -= (SystemInformation.HorizontalScrollBarThumbWidth + 2);
                }

                return resual;
            }
            else
            {
                return 0;
            }
        }

        //计算FlowPanel的左边距
        private int CalcPanelLeft()
        {
            if (GridSource != null)
            {
                var resual = 0;

                if (GridSource.RowHeadersVisible)
                {
                    resual = HeaderTextLabel.Width + SystemInformation.BorderSize.Width * 2;
                }
                else
                {
                    resual = 0;
                }

                return resual;
            }
            else
            {
                return HeaderTextLabel.Width + SystemInformation.BorderSize.Width * 2;
            }
        }

        //计算滚动条的最大值
        private void LayoutScollValue()
        {
            var i = 0;

            var columnsWidth = GridSource.Columns.GetColumnsWidth(DataGridViewElementStates.Visible);

            if (GridSource.RowHeadersVisible)
            {
                i += GridSource.RowHeadersWidth;
            }

            if (IsGridHasHScollBar())
            {
                i += SystemInformation.HorizontalScrollBarThumbWidth;

                panelLabelCollection.Width = CalcPanelWidth();
            }

            panelLabelCollection.HorizontalScroll.Maximum = columnsWidth + i;
        }

        //判断当前的DataGridView是否已经出现水平滚动条,如果出现,这FlowPanel的宽度就要减去滚动条的宽度
        private bool IsGridHasHScollBar()
        {
            var columnsWidth = GridSource.Columns.GetColumnsWidth(DataGridViewElementStates.Visible);

            if ((GridSource.ScrollBars == ScrollBars.Horizontal || GridSource.ScrollBars == ScrollBars.Both) && columnsWidth > GridSource.ClientSize.Width)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        private void HandleEvents(DataGridView dg)
        {
            dg.Columns.CollectionChanged += Columns_CollectionChanged;
            dg.CellValueChanged += GridSource_CellValueChanged;
            dg.RowsAdded += GridSource_RowsAdded;
            dg.Resize -= GridSource_Resize;
            dg.ColumnWidthChanged += GridSource_ColumnWidthChanged;
            dg.Scroll += GridSource_Scroll;
        }

        private void UnHandleEvents(DataGridView dg)
        {
            dg.Columns.CollectionChanged -= Columns_CollectionChanged;
            dg.CellValueChanged -= GridSource_CellValueChanged;
            dg.RowsAdded -= GridSource_RowsAdded;
            dg.Resize -= GridSource_Resize;
            dg.ColumnWidthChanged -= GridSource_ColumnWidthChanged;
            dg.Scroll -= GridSource_Scroll;
        }

        //创建一个新的合计单元格Label控件
        private Label BuildSumLabel(DataGridViewColumn column)
        {
            var lbl = new Label();

            lbl.Width = column.Width;// +column.DividerWidth;
            lbl.Height = panelLabelCollection.ClientSize.Height;
            lbl.BackColor = this.TotalCellBackColor;
            lbl.ForeColor = this.TotalCellForeColor;
            lbl.TextAlign = ContentAlignment.MiddleCenter;
            lbl.BorderStyle = this.TotalCellBorderStyle;

            lbl.Margin = new Padding(0, 0, 0, 0);

            return lbl;
        }



        protected delegate string CellValueFormater(object value, string formatString);

        #region "类型格式化器"



        #endregion
    }

    public class TotalColumnConfig
    {
        public TotalColumnConfig()
            : this("")
        { }

        public TotalColumnConfig(string formatString)
        {
            FormatString = formatString;
        }

        public string FormatString { set; get; }
    }
}
